package com.actionscriptclass.timer
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.TimerEvent;
    import com.actionscriptclass.dataholder.IDataHolder;
    import flash.utils.Timer;
 
    
    //its not possible to extend Timer because Timer constructor must not be call on creating instance of this class
	public class TimerInvoker extends EventDispatcher
	{
		//mainTimer
        private var _timer:Timer;
	    //number of loops
		private var _loopNumber:int;
		//current loop iteration
	    private var _currentLoopNumber:uint;
		//data - function to execute,repeater, delay
		private var  _dataHolderFunctions:IDataHolder; 
		 
		public function TimerInvoker():void
		{
		   _currentLoopNumber=0;
        }
	 	
	  //adding new IDataHolder when DataHolder data is change
	  //SetState.as is updating this changes
	  //it alaway update IDataHolder type so dataHolder that contain data about repeat,delay,func,class prop etc. must implement IDataHolder
	  	public function addFunctions(data:IDataHolder):void
	  	{
	    	_dataHolderFunctions=data
	  	} 
	  
		//main engine of timer, when its finish then reset timer and if needed then start again(loop)
	    private function timerIteration(event:TimerEvent):void
		{	  
		  	//check if _dataHolderFunctions.repeat is 0. If 0 loop is endless 
			if(_dataHolderFunctions.repeat!=0)
		    {
		    	///exe function
			    _dataHolderFunctions.functionExec(_timer.currentCount-1);
				_timer.delay= _dataHolderFunctions.getDelay(_timer.currentCount-1);
				//check if timer reach end      
				if(_timer.currentCount==_dataHolderFunctions.repeat)
				{ 	  
				    _timer.reset()
				    setLoop();
				}   
		    }
			else
			{
		    	_dataHolderFunctions.functionExec(0);
			}
		}	
	   //seting up timer and start a timer.
		public  function setTimer():void
		{
		   _dataHolderFunctions.processData();	 
	       _timer = new Timer(_dataHolderFunctions.getDelay(0) ,_dataHolderFunctions.repeat);
		   _timer.addEventListener(TimerEvent.TIMER,timerIteration)
	 	   _timer.start();  
	 	}
	 
	     //check if looop is needed, user have option to play loop.
		 private function setLoop():void
		 {	    
		    if (_loopNumber!=_currentLoopNumber) 
			{ 
			    _timer.start();  
			    _currentLoopNumber++
		    }
			else
			{
			   dispatchEvent(new Event("IntervalEnd"));
			}
	  	 }
		 ///when loop play his part then is set to 0
		 private function resetLoop():void
		 {
		 	_loopNumber =0
		    _currentLoopNumber=0
		 }
		
	
		////////////////////////////REST of methods are managing timer interface (SetState.as)
		 public function start():void
		 {
		   if(_timer==null)
		   {
		   	setTimer()
		   } 
		   else
		   {
		   	_timer.start()
		   	 
		   }
		 }	
		 
		 public function stop():void
		 {
		 	_timer.reset();
		    resetLoop()
		 }
		 
		 public function pause():void
		 {
		    _timer.stop();
		 }
		 
		 public function loop(loopNumber:uint):void
		 { 
		 	 //if user set loop number to 0 it is endless loop
			//_loopNumber!=_currentLoopNumber is allways true so loop is endless
			if(loopNumber==0)
			{
			    _loopNumber=-1
			}
			else
			{
				_loopNumber=loopNumber
			}
			
			
			if(_timer==null)
			{
			   setTimer()
			} 
			else
			{
			   _timer.start()
	        }
	     }
	 
	}
}
 